package cn.qu.phizline.event;

import cn.qu.phizline.common.ByteBuffer;
import cn.qu.phizline.common.TypeUtils;

/**
 * Created by zh on 2017/10/25.
 */
public abstract class PayloadConventer {

    protected abstract byte[] toPayloadBytes(Body body);

    protected abstract Body parsePayloadBody(Class<? extends Body> bodyClazz, byte[] bytes);

    public byte[] toBytes(Payload payload) {
        byte[] bodys = toPayloadBytes(payload.getBody());

        // type 4+version 4+body.length 8+body
        ByteBuffer buffer = new ByteBuffer(4 + 4 + 8 + bodys.length);

        buffer.uint4(payload.getType());
        buffer.uint4(payload.getVersion());
        buffer.uint8(bodys.length);
        buffer.write(bodys);

        buffer.position(0);
        return buffer.toBytes();
    }

    public <T extends Payload> T fromBytes(Class<? extends Payload> clazz, byte[] bytes) {
        Payload payload = TypeUtils.newInstance(clazz);
        Body body = parsePayloadBody(payload.getBodyType(), bytes);
        payload.setBody(body);

        return (T) payload;
    }
}
